package com.vue.admin.service.common.mybatis.dao;

import com.vue.admin.service.common.jwt.ShiroUtil;
import com.vue.admin.service.common.mybatis.entity.BaseEntity;
import com.vue.admin.service.common.mybatis.entity.Page;
import com.vue.admin.service.common.mybatis.entity.Query;
import com.vue.admin.service.common.mybatis.mapper.BaseDefMapper;
import com.vue.admin.service.common.util.CommonUtils;
import com.vue.admin.service.module.sys.entity.UserEntity;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.Sqls;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @program: vue-admin-service
 * @description: 通用数据持久层封装接口实现类
 * @author: zhangyangyang
 * @create: 2020-04-03 11:09
 **/
public abstract class BaseDAOImpl<T extends BaseEntity,E> implements BaseDAO<T, E> {
    /**
     * 获取抽象mapper
     *
     * @return
     */
    public abstract BaseDefMapper<T, E> getMapper();

    /**
     * 基础实体保存
     *
     * @param record
     * @return
     */
    @Override
    public int insert(T record) {
        Date d = new Date();
        //第一次插入修改时间与创建时间一致
        record.setUpdateTime(d);
        //设置默认处理时间
        record.setCreateTime(d);
        if (CommonUtils.isNullOrEmpty(record.getCreateUser())) {
            UserEntity entity = ShiroUtil.getUserEntity();
            if (!CommonUtils.isNullOrEmpty(entity)) {
                //设置创建人
                record.setCreateUser(entity.getId());
                record.setUpdateUser(entity.getId());
            }
        }
        if (CommonUtils.isNullOrEmpty(record.getDeleted())) {
            //如果删除标志位为空，默认设置为未删除
            record.setDeleted(0);
        }
        return this.getMapper().insert(record);
    }

    /**
     * 批量保存数据
     *
     * @param recordList
     * @return
     */
    @Override
    public int insertList(List<T> recordList) {
        //循环设置处理人和处理时间
        for (T record : recordList) {
            //获取服务器时间
            Date date = new Date();
            record.setCreateTime(date);
            record.setUpdateTime(date);
            if (CommonUtils.isNullOrEmpty(record.getCreateUser())) {
                UserEntity entity = ShiroUtil.getUserEntity();
                if (!CommonUtils.isNullOrEmpty(entity)) {
                    //设置创建人
                    record.setCreateUser(entity.getId());
                }
            }
            if (CommonUtils.isNullOrEmpty(record.getDeleted())) {
                //如果删除标志位为空，默认设置为未删除
                record.setDeleted(0);
            }
        }
        //批量插入
        return this.getMapper().insertList(recordList);
    }

    /**
     * 更新
     *
     * @param record
     * @return
     */
    @Override
    public int updateByPrimaryKey(T record) {
        if (CommonUtils.isNullOrEmpty(record.getCreateUser())) {
            UserEntity entity = ShiroUtil.getUserEntity();
            if (!CommonUtils.isNullOrEmpty(entity)) {
                //设置修改人
                record.setCreateUser(entity.getId());
            }
        }
        //设置修改时间
        record.setUpdateTime(new Date());
        return this.getMapper().updateByPrimaryKey(record);
    }

    /**
     * 更新 与上一个方法区别是是否将空属性更新到数据库
     * 此方法不会将空数据更新到数据库
     *
     * @param record
     * @return
     */
    @Override
    public int updateByPrimaryKeySelective(T record) {
        if (CommonUtils.isNullOrEmpty(record.getCreateUser())) {
            UserEntity entity = ShiroUtil.getUserEntity();
            if (!CommonUtils.isNullOrEmpty(entity)) {
                //设置修改人
                record.setCreateUser(entity.getId());
            }
        }
        //设置修改时间
        record.setUpdateTime(new Date());
        return this.getMapper().updateByPrimaryKeySelective(record);
    }

    /**
     * 批量更新 NOTE:返回影响行数目前不正确
     *
     * @param recordList
     * @return
     */
    @Override
    public int updateListByPrimaryKeySelective(List<T> recordList) {
        //循环设置处理人和处理时间
        for (T record : recordList) {
            //获取服务器时间
            Date date = new Date();
            record.setUpdateTime(date);
            if (CommonUtils.isNullOrEmpty(record.getCreateUser())) {
                UserEntity entity = ShiroUtil.getUserEntity();
                if (!CommonUtils.isNullOrEmpty(entity)) {
                    //设置修改人
                    record.setUpdateUser(entity.getId());

                }
            }
        }
        return this.getMapper().updateListByPrimaryKeySelective(recordList);
    }

    /**
     * 逻辑删除
     *
     * @param id
     * @return
     */
    @Override
    public int deleteByPrimaryKeyByLogic(E id) {
        T record = this.getMapper().selectByPrimaryKey(id);
        //设置删除
        record.setDeleted(1);
        return this.updateByPrimaryKeySelective(record);
    }

    /**
     * 批量逻辑删除 NOTE:返回影响行数目前不正确
     *
     * @param ids
     * @param clazz
     * @return
     */
    @Override
    public int deleteListByPrimaryKeyByLogic(E[] ids, Class<T> clazz) {
        List<T> recordList = this.getListByIds(ids, clazz);
        for (T record : recordList) {
            //设置删除字段
            record.setDeleted(1);
        }
        return this.updateListByPrimaryKeySelective(recordList);
    }

    /**
     * 物理删除
     *
     * @param id
     * @return
     */
    @Override
    public int deleteByPrimaryKey(E id) {
        return this.getMapper().deleteByPrimaryKey(id);
    }

    /**
     * 物理批量删除
     *
     * @param ids
     * @param clazz
     * @return
     */
    @Override
    public int deleteListByPrimaryKey(List<E> ids, Class<T> clazz) {
        return this.getMapper().deleteListByPrimaryKey(ids, clazz);
    }

    /**
     * 根据主键ID获取list
     *
     * @param ids
     * @param clazz
     * @return
     */
    @Override
    public List<T> getListByIds(E[] ids, Class<T> clazz) {
        Example example = Example.builder(clazz)
                .where(Sqls.custom().andIn("id", Arrays.asList(ids)))
                .build();
        return this.getMapper().selectByExample(example);
    }

    /**
     * 根据主键获取数据
     *
     * @param id
     * @return
     */
    @Override
    public T getByPrimaryKey(E id) {
        return this.getMapper().selectByPrimaryKey(id);
    }

    /**
     * 分页查询 note需要自己在mapper.xml中实现
     *
     * @param page
     * @param query
     * @return
     */
    @Override
    public List<T> listForPage(Page<T> page, Query query) {
        return this.getMapper().listForPage(page, query);
    }

    /**
     * list数据 note需要自己在mapper.xml中实现
     *
     * @param query
     * @return
     */
    @Override
    public List<T> list(Query query) {
        //添加筛选逻辑删除标识
        if (!query.containsKey("deleted")) {
            //默认查询未被逻辑删除的数据
            query.put("deleted", 0);
        }
        return this.getMapper().list(query);
    }

    @Override
    public T selectOne(T record) {
        if (CommonUtils.isNullOrEmpty(record.getDeleted())) {
            //默认查询未被逻辑删除的数据
            record.setDeleted(0);
        }
        return this.getMapper().selectOne(record);
    }

    @Override
    public List<T> selectList(T record) {
        if (CommonUtils.isNullOrEmpty(record.getDeleted())) {
            //默认查询未被逻辑删除的数据
            record.setDeleted(0);
        }
        return this.getMapper().select(record);
    }
}
